﻿using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;

namespace WorseGame.Content
{
    public class 动物饿死(IMonitor 监视器, IModHelper 助手)
    {
        private readonly IMonitor 监视器 = 监视器;
        private readonly IModHelper 助手 = 助手;
        private const int 饿死天数 = 5;
        private readonly Dictionary<long, int> 动物饥饿天数 = [];
        private bool 已初始化 = false;
        public void Initialize()
        {
            助手.Events.GameLoop.DayStarted += 每日开始时;
            助手.Events.GameLoop.SaveLoaded += 存档加载时;
        }
        private void 存档加载时(object? sender, SaveLoadedEventArgs e)
        {
            加载动物数据();
            已初始化 = true;
        }

        private void 每日开始时(object? sender, DayStartedEventArgs e)
        {
            if (已初始化)
            {
                检查所有动物();
            }
        }

        private void 检查所有动物()
        {
            var 所有动物 = 获取所有动物();
            var 要移除的动物 = new List<FarmAnimal>();
            foreach (var 动物 in 所有动物)
            {
                if (动物 != null)
                {
                    bool 今天被喂食 = 检查动物是否被喂食(动物);
                    if (今天被喂食)
                    {
                        重置动物饥饿(动物);
                    }
                    else
                    {
                        增加动物饥饿(动物);

                        int 当前饥饿天数 = 获取动物饥饿天数(动物);
                        if (当前饥饿天数 >= 饿死天数 - 2)
                        {
                            显示饥饿警告(动物, 当前饥饿天数);
                        }
                        if (当前饥饿天数 >= 饿死天数)
                        {
                            要移除的动物.Add(动物);
                        }
                    }
                }
            }
            foreach (var 动物 in 要移除的动物)
            {
                动物饿死了(动物);
            }
            保存动物数据();
        }

        private static bool 检查动物是否被喂食(FarmAnimal 动物)
        {
            if (动物.fullness.Value > 0 || 动物.isEating.Value || 动物.happiness.Value > 200)
            {
                return true;
            }
            return false;
        }

        private static List<FarmAnimal> 获取所有动物()
        {
            var 所有动物 = new List<FarmAnimal>();
            if (Game1.getFarm() != null)
            {
                所有动物.AddRange(Game1.getFarm().animals.Values);
            }
            foreach (var 位置 in Game1.locations)
            {
                if (位置?.buildings != null)
                {
                    foreach (var 建筑 in 位置.buildings)
                    {
                        if (建筑?.indoors?.Value?.animals != null)
                        {
                            所有动物.AddRange(建筑.indoors.Value.animals.Values);
                        }
                    }
                }
            }

            return 所有动物;
        }

        private void 增加动物饥饿(FarmAnimal 动物)
        {
            long 动物ID = 动物.myID.Value;

            if (动物饥饿天数.TryGetValue(动物ID, out int value))
            {
                动物饥饿天数[动物ID] = ++value;
            }
            else
            {
                动物饥饿天数[动物ID] = 1;
            }
        }
        private void 重置动物饥饿(FarmAnimal 动物)
        {
            long 动物ID = 动物.myID.Value;
            if (动物饥饿天数.TryGetValue(动物ID, out int value) && value > 0)
            {
                动物饥饿天数[动物ID] = 0;              
            }
        }
        private int 获取动物饥饿天数(FarmAnimal 动物)
        {
            long 动物ID = 动物.myID.Value;
            return 动物饥饿天数.GetValueOrDefault(动物ID, 0);
        }
        private static void 显示饥饿警告(FarmAnimal 动物, int 饥饿天数)
        {
            int 剩余天数 = 饿死天数 - 饥饿天数;
            if (剩余天数 == 2)
            {
                Game1.addHUDMessage(new HUDMessage($"{动物.displayName} 看起来很饿，再不喂食就危险了！", 2));
            }
            else if (剩余天数 == 1)
            {
                Game1.addHUDMessage(new HUDMessage($"{动物.displayName} 快要饿死了！请立即喂食！", 3));
                Game1.playSound("skeletonDie");
            }
        }

        private void 动物饿死了(FarmAnimal 动物)
        {
            long 动物ID = 动物.myID.Value;
            string 动物名称 = 动物.displayName;           
            if (Game1.getFarm()?.animals?.ContainsKey(动物ID) == true)
            {
                Game1.getFarm().animals.Remove(动物ID);
            }
            foreach (var 位置 in Game1.locations)
            {
                if (位置?.buildings != null)
                {
                    foreach (var 建筑 in 位置.buildings)
                    {
                        if (建筑?.indoors?.Value?.animals?.ContainsKey(动物ID) == true)
                        {
                            建筑.indoors.Value.animals.Remove(动物ID);
                        }
                    }
                }
            }
            动物饥饿天数.Remove(动物ID);
            string 死亡消息 = $"{动物名称} 因为长期饥饿而死亡了...";
            Game1.addHUDMessage(new HUDMessage(死亡消息, 3));
            Game1.playSound("death");           
        }

        private void 保存动物数据()
        {
            var 数据列表 = new List<string>();
            foreach (var kvp in 动物饥饿天数)
            {
                数据列表.Add($"{kvp.Key}:{kvp.Value}");
            }
            string 保存数据 = string.Join(";", 数据列表);
            助手.Data.WriteSaveData("AnimalStarvationData", 保存数据);
        }

        private void 加载动物数据()
        {
            string? 保存数据 = 助手.Data.ReadSaveData<string>("AnimalStarvationData");
            if (!string.IsNullOrEmpty(保存数据))
            {
                动物饥饿天数.Clear();
                var 数据数组 = 保存数据.Split(';');
                foreach (var 数据项 in 数据数组)
                {
                    if (!string.IsNullOrEmpty(数据项))
                    {
                        var 键值对 = 数据项.Split(':');
                        if (键值对.Length == 2)
                        {
                            long 动物ID = long.Parse(键值对[0]);
                            int 饥饿天数 = int.Parse(键值对[1]);
                            动物饥饿天数[动物ID] = 饥饿天数;
                        }
                    }
                }
            }
        }      
    }
}